using System;
using System.Collections;
using System.Html;
using System.Runtime.CompilerServices;
using Awaiter;
using Nsb;
using Nsb.Classes;
using ThemeChain;
using Yoshi.Classes;
using jQueryApi;

namespace PlaySpace.Classes
{
    [IgnoreNamespace]
    public static class Spaces
    {
        public const string LogSiteKey = "LogSite";

        public static void Page()
        {
            SiteHelpers.ForVersion("../creator", delegate(string n, string v) { jQuery.Select("#CreatorVersion").Html("Creator Version " + v); });
            SiteHelpers.ForVersion("../", delegate(string n, string v) { jQuery.Select("#PlayNexusVersion").Html("PlayNexus Version " + v); });

            jQuery.Select("#UpdateAllBtn").Click(UpdateAllEv);

            new Await()
                .AddAw(FileBlobBase.GetDirAw, Site.SpacesPath)
                .AddDx(
                    delegate(Await aw)
                    {
                        Site.Map = (DirMap)aw.Result;
                        string host = Uri.Front(Window.Location.Href);
                        host = host.Substr(0, host.Length - "creator".Length);

                        jQueryObject el = jQuery.FromHtml("<div id='SpacesList'/>").AppendTo(jQuery.Select("#Sites").Empty());

                        jQueryObject body = jQuery.FromHtml("<tbody/>")
                            .AppendTo(jQuery.FromHtml("<table/>").AppendTo(el))
                            ;

                        AddSiteRow(body, host, "root");

                        foreach (string site in Site.Map.dirs)
                        {
                            AddSiteRow(body, host + "/spaces", site);
                        }
                    }
                )
                .AddDx(
                    delegate
                    {
                        if (ThemeYoshi.CurrentPage.Admin)
                            jQuery.Select("#LogOutput").Closest(".Gig").Hide();

                        if (Window.Location.Hostname == "love.playnexus.com")
                        {
                            jQuery.Select("#PublishLiveBtn")
                                .Click(PublishLiveEv)
                                ;
                            jQuery.Select("#PublishLiveAllBtn")
                                .Click(PublishLiveAllEv)
                                ;
                        }
                        else
                        {
                            jQuery.Select("#PublishLiveBtn")
                                .Attribute("disabled", "disabled")
                                .Attribute("title", "only available on dev site")
                                ;
                            jQuery.Select("#PublishLiveAllBtn")
                                .Attribute("disabled", "disabled")
                                .Attribute("title", "only available on dev site")
                                ;
                        }
                    }
                )
                .Commit();
        }

        private static void AddSiteRow(jQueryObject body, string host, string site)
        {
            jQueryObject tr = jQuery.FromHtml("<tr/>").AppendTo(body);

            jQuery.FromHtml("<td/>")
                .AppendTo(tr)
                .Append(jQuery.FromHtml("<a class='Site' target='_blank'/>").Html(site).Attribute(new Dictionary("href", Uri.Join(host, site, ThemeYoshi.MasterPage))))
                ;

            jQuery.FromHtml("<td/>")
                .AppendTo(tr)
                .Attribute("id", "Vx" + site)
                ;

            jQuery.FromHtml("<td class='SpaceBtn UpdateBtn'/>")
                .AppendTo(tr)
                .Html("update")
                .Click(UpdateSiteCv(site))
                ;

            jQuery.FromHtml("<td class='SpaceBtn LogsBtn'/>")
                .AppendTo(tr)
                .Html("logs")
                .Click(GoToLogsCv(site))
                ;

            jQuery.FromHtml("<td/>")
                .AppendTo(tr)
                .Append(
                    jQuery.FromHtml("<div class='DelBtn'/>")
                    .Html("\u2716" /*thick x*/)
                    .Attribute("title", "delete this space")
                    .Attribute("id", "DEL" + site)
                    .Click(Site.SpaceDelUx(site))
                    )
                ;

            SiteHelpers.ForVersion(site, delegate(string n, string v) { jQuery.Select("#Vx" + n).Html(v); });
        }

        public static jQueryEventHandler GoToLogsCv(string site)
        {
            return delegate(jQueryEvent e)
            {
                DomElement.CancelEvent(e);
                Storage.SetSession(LogSiteKey, site);
                Master.GoPage(ThemeYoshi.DefaultPageClass, "syslogs");
            };
        }

        public static void UpdateAllEv(jQueryEvent e)
        {
            foreach (string site in Site.Map.dirs)
            {
                jQueryEventHandler fn = UpdateSiteCv(site);
                fn(e);
            }
        }

        public static jQueryEventHandler UpdateSiteCv(string site)
        {
            return delegate(jQueryEvent e)
                   {
                       DomElement.CancelEvent(e);
                       CreateSpaceItem csi = new CreateSpaceItem();
                       csi.Name = site;
                       UpdateSpaceAw(Await.AsyncAw, csi);
                   };
        }

        public static void UpdateSpaceAw(Await awp, CreateSpaceItem csi)
        {
            int start = (new Date()).GetTime();
            string msg = String.Format(" - updating space name={0}", csi.Name);
            Inform.Event("Spaces.UpdateSpaceAw", msg);
            Exceptions.SaveLog("build", "beginning" + msg);
            Cluster.Spinner(true, .35);

            csi.CreateTime = (new Date()).GetTime();

            Dictionary args = new Dictionary(
                "password", Storage.GetLocal(ThemeYoshi.CuratePasswordKey),
                "spaceName", csi.Name,
                "update", true
                );

            jQueryAjaxOptions options = new jQueryAjaxOptions();
            options.Url = Uri.App("ph/createspace.php");
            options.DataType = "json";
            options.Data = args;
            options.Type = "GET";

            options.Success =
                delegate(object data, string textStatus, jQueryXmlHttpRequest request1)
                {
                    Cluster.Spinner(false);
                    Dictionary result = (Dictionary)data;

                    if ((bool)result["result"])
                    {
                        SiteHelpers.ForVersion(csi.Name, delegate(string n, string v) { jQuery.Select("#Vx" + n).Html(v); });

                        // Rebuild the javascript package
                        string url = String.Format("../spaces/{0}/Scripts/{1}?minimize=y", csi.Name, ThemeYoshi.MasterScripts);
                        new Await()
                            .LoadScript(Uri.Uniqueify(url))
                            .AddDx(delegate { Exceptions.SaveLog("build", String.Format("finished{0} time={1}ms", msg, (new Date()).GetTime() - start)); })
                            .Commit(awp);
                        return;
                    }
                    awp.Done();
                };

            options.Error =
                delegate(jQueryXmlHttpRequest request, string textStatus, Exception error)
                {
                    Cluster.Spinner(false);
                    Inform.Error(String.Format("Error creating space {0}, {1} {2}", csi.Name, textStatus, error));
                    awp.Handle(new Exception(Exceptions.BlobLoadError));
                };
            jQuery.Ajax(options);
        }

        public static void PublishLiveEv(jQueryEvent e)
        {
            DomElement.CancelEvent(e);
            PublishLive(new Dictionary());
        }

        public static void PublishLiveAllEv(jQueryEvent e)
        {
            DomElement.CancelEvent(e);
            PublishLive(new Dictionary("alldata", true));
        }

        public static void PublishLive(Dictionary opts)
        {
            new Await()
                .AddAw(new Ask().OkCancelAw, new Dictionary("Msg", String.Format("Publish {0} for sure?", (bool)opts["alldata"] ? "ALL" : "software")))
                .AddAw(DomElement.RequireResultAw, true)
                .AddDx(
                    delegate(Await aw)
                    {
                        int start = (new Date()).GetTime();
                        string msg = String.Format(" - publishing to PlayNexus");
                        Inform.Debug(msg);
                        Exceptions.SaveLog("build", "beginning" + msg);
                        Cluster.Spinner(true, .35);
                        Dictionary args = new Dictionary(
                            "password", Storage.GetLocal(ThemeYoshi.CuratePasswordKey)
                            );

                        args = (Dictionary) jQuery.Extend(args, opts);

                        jQueryAjaxOptions options = new jQueryAjaxOptions();
                        options.Url = Uri.App("ph/publishpnx.php");
                        options.DataType = "json";
                        options.Data = args;
                        options.Type = "GET";

                        options.Success =
                            delegate(object data, string textStatus, jQueryXmlHttpRequest request1)
                            {
                                Dictionary result = (Dictionary) data;

                                jQuery.Select("#LogOutput").Html(Transform.Htmlize(Rx.PrettyJson(data))).Closest(".Gig").Show();

                                if ((bool) result["result"])
                                {
                                    // Rebuild the javascript packages on PlayNexus.com and PlayNexus.com/creator
                                    string url1 = String.Format("http://www.playnexus.com/Scripts/{0}?minimize=y", ThemeYoshi.MasterScripts);
                                    string url2 = String.Format("http://www.playnexus.com/creator/Scripts/{0}?minimize=y", ThemeYoshi.MasterScripts);
                                    new Await()
                                        .LoadScript(Uri.Uniqueify(url1))
                                        .LoadScript(Uri.Uniqueify(url2))
                                        .AddDx(delegate { Cluster.Spinner(false); })
                                        .AddDx(delegate { Exceptions.SaveLog("build", String.Format("finished{0} time={1}ms", msg, (new Date()).GetTime() - start)); })
                                        .Commit(aw);
                                    return;
                                }
                                aw.Done();
                            };

                        options.Error =
                            delegate(jQueryXmlHttpRequest request, string textStatus, Exception error)
                            {
                                Cluster.Spinner(false);
                                Inform.Error(String.Format("Error publishing live {0} {1}", textStatus, error));
                                aw.Done();
                            };
                        jQuery.Ajax(options);
                    })
                .Commit();
        }
    }
}
